package com.java.controller;

import com.java.entity.User;
import com.java.entity.factory.UserFactoryBean;
import com.java.service.WeclomeService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/**
 * @Author: 司军强
 * @Date: 2020/03/19/9:44
 * @Description: 通过xml方式的方法获取bean实例
 * 思路：1：解析配置  2：定位与注册对象  3：注入对象
 */
// 这个注解标志着当前类是个配置类，他的作用就和xml的配置文件一样
@Configuration

//通过@compontScan 这个注解指定要扫描包下面被标记的注解
@ComponentScan("com.java")
public class Entrance {


	/**
	 * 通过xml的方式 获取spring容器管理的bean
	 */
	public static void main(String[] args) {

		System.out.println("hello spring-resource");
		String xmlPathUrl = "D:\\library\\code\\spring_farmwork_source_code\\springDemo\\src\\main\\resources\\spring-config.xml";

		//将xml面的配置文件注入到spring容器中
		ApplicationContext applicationContext = new FileSystemXmlApplicationContext(xmlPathUrl);

		//通过spring容器获取bean的实例
		WeclomeService welcomeService = (WeclomeService) applicationContext.getBean("welcomeService");
		welcomeService.sayHello(":superman-spring");

		//使用无参构造函数创建对象
		User user1a = (User) applicationContext.getBean("user1");
		User user1b = (User) applicationContext.getBean("user1");

		// 使用静态工厂创建对象
		User user2a = (User) applicationContext.getBean("user2");
		User user2b = (User) applicationContext.getBean("user2");

		// 使用实例化工厂创建对象
		User user3a = (User) applicationContext.getBean("user3");
		User user3b = (User) applicationContext.getBean("user3");

		// 对上面的结果进行输出
		System.out.println("use no param constructor create object :" + user1a);
		System.out.println("use no param constructor create object :" + user1b);

		System.out.println("use static factory create object :" + user2a);
		System.out.println("use static factory create object :" + user2b);

		System.out.println("use instance factory create object :" + user3a);
		System.out.println("use instance factory create object :" + user3b);

		//4: 测试使用FactoryBean 生成普通的bean
		User userFactoryBean = (User) applicationContext.getBean("userFactoryBean");
		System.out.println("user factoryBean create Object:" + userFactoryBean);

		// 5：测试 使用 "&" 生成FactoryBean的实例
		UserFactoryBean factoryBean = (UserFactoryBean) applicationContext.getBean("&userFactoryBean");
		System.out.println("user & create UserFactoryBean object:" + factoryBean);
		// TODO: 2020/5/4  6-3 击破简单容器  05:29
	}

	/**
	 * 铜过注解的方式获取容器的中的bean
	 */
	public static void main2(String[] args) {

		/*创建以一个注解标记配置的上下文,并指定被配置注解标记的类 ，和上面的FileSystemXmlApplicationContext()获取的上下文一样只不过是 一个是通过注解一个是通过xml*/
		ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Entrance.class);

		/* 获取sping 工厂所有的的bean名字*/
		String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
		int beanDefinitionCount = applicationContext.getBeanDefinitionCount();

		for (String beanDefinitionName : beanDefinitionNames) {
			System.out.println("container bean name:" + beanDefinitionName);
		}
		System.out.println(" container all bean count: " + beanDefinitionCount);

		//根据bean的名字,获取对应的实例,并且调用该方法,注意这个参数是小写的 可以从beanDefinitionName 这个里面查看
		try {
			WeclomeService weclomeService = (WeclomeService) applicationContext.getBean("welcomeServiceImpl");
			WelcomeController welcomeController = (WelcomeController) applicationContext.getBean("welcomeController");
			welcomeController.handRequest();
			weclomeService.sayHello(":strong springframework");
		} catch (BeansException e) {
			System.out.println("beanException :check bean name value");
			e.printStackTrace();
		}
	}


}
